altp2m: Prevent deadlocks when a domain performs altp2m operations on itself
authorGeorge Dunlap <george.dunlap@citrix.com>
Mon, 18 Feb 2019 12:45:24 +0000 (13:45 +0100)
committerJan Beulich <jbeulich@suse.com>
Mon, 18 Feb 2019 12:45:24 +0000 (13:45 +0100)
commit29d28b29190ba09d53ae7e475108def84e16e363
tree978e34a8f353cd0c9460467b479598f73d1c7080
parentfbaa0e58f39ae23263ad0935d88a7e61e0dd9ef1
altp2m: Prevent deadlocks when a domain performs altp2m operations on itself

domain_pause_except_self() was introduced to allow a domain to pause
itself while doing altp2m operations.  However, as written, it has a
risk fo deadlock if two vcpus enter the loop at the same time.

Luckily, there's already a solution for this: Attempt to call domain's
hypercall_deadlock_mutex, and restart the entire hypercall if you
fail.

Make domain_pause_except_self() attempt to grab this mutex when
pausing itself, returning -ERESTART if it fails.  Have the callers
check for errors and pass the value up.  In both cases, the top-level
do_hvm_op() should DTRT when -ERESTART is returned.

The (necessary) reuse of the hypercall deadlock mutex poses the risk
of getting called from a context where the lock was already acquired
(e.g. someone may (say) call domctl_lock(), then afterwards call
domain_pause_except_self()). However, in the interest of not
overcomplicating things, no changes are made here to the mutex.
Attempted nesting of this lock isn't a security issue, because all
that will happen is that the vcpu will livelock taking continuations.

Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Tested-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Juergen Gross <jgross@suse.com>
xen/arch/x86/mm/p2m.c
xen/common/domain.c
xen/include/xen/sched.h